package com.thinkgem.jeesite.common.utils;

import com.thinkgem.jeesite.modules.book.entity.BkBookinfo;
import com.thinkgem.jeesite.modules.book.entity.CNMARC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by aulbrother on 2015/10/28.
 */
public class MarcUtils{

    private static Logger logger = LoggerFactory.getLogger(MarcUtils.class);

    private static BufferedReader getBufferedReader(InputStream inputStream, String charsetName) throws IOException{
        return new BufferedReader(new InputStreamReader(inputStream, charsetName));
    }
    public static String makeMarc(BkBookinfo bookinfo){
        String id= bookinfo.getId();
        String isbn = bookinfo.getIsbn();
        String price = bookinfo.getPrice();

        String marcStra = "0" + id.substring(id.length() - 4) + "nam0 22@leg@   45  ";
        String marcStrb = "";
        String marcTem = "";
        // 001
        marcStrb += "\u001E0000903986";
        marcStra += "001001100000";
        // 005
        int start = marcStrb.length();
        marcTem = CNMARC.RS + "20150202162918.0";
        marcStrb += marcTem;
        marcStra += "005" + getNum(getWordlength(marcTem), 4) + getNum(start, 5);

        // 010
        start = marcStrb.length();
        marcTem = CNMARC.RS + "  " + CNMARC.US + "a978-7-300-19925-2" + CNMARC.US + "dCNY180.00";
        marcStrb += marcTem;
        marcStra += "010" + getNum(getWordlength(marcTem), 4) + getNum(start, 5);

        // 200
        start = getWordlength(marcStrb);
        marcTem = CNMARC.RS + "1 " + CNMARC.US + "a" + bookinfo.getBookname() + CNMARC.US + "f" + bookinfo.getAuthor();
        marcStrb += marcTem;
        marcStra += "200" + getNum(getWordlength(marcTem), 4) + getNum(start, 5);

        // 210
        start = getWordlength(marcStrb);
        marcTem = CNMARC.RS + "  " + CNMARC.US + "a" + bookinfo.getPubplace() + CNMARC.US + "c" + bookinfo.getPublisher() + CNMARC.US + "d" + bookinfo.getPubdate();
        marcStrb += marcTem;
        marcStra += "210" + getNum(getWordlength(marcTem), 4) + getNum(start, 5);

        // 215
        start = getWordlength(marcStrb);
        marcTem = CNMARC.RS + "  " + CNMARC.US + "a" + bookinfo.getPages() + CNMARC.US + "d" + bookinfo.getMeasure();
        marcStrb += marcTem;
        marcStra += "215" + getNum(getWordlength(marcTem), 4) + getNum(start, 5);

        // 225


        int marcStral = getWordlength(marcStra);
        marcStra = marcStra.replace("@leg@", getNum(marcStral, 5));

        return marcStra + "         " + marcStrb;
    }


    public static List<BkBookinfo> readMarc(InputStream inputStream, String charsetName){
        List<BkBookinfo> bookInfoList = new ArrayList<>();
        Map<String, CNMARC> cnmarcs;
        CNMARC cnmarc;
        try{
            BufferedReader br = getBufferedReader(inputStream, charsetName);
            String line;
            String temBookInfoStr = "";
            while((line = br.readLine()) != null){
                line = temBookInfoStr + line;

                String[] bookInfoStrs = line.split(CNMARC.GS);
                for(String bookInfoStr : bookInfoStrs){
                    try{
                        cnmarcs = new LinkedHashMap<>();
                        System.out.println(bookInfoStr);
                        byte bytes[] = bookInfoStr.getBytes(charsetName);
                        // 读取此条数据的总长度
                        byte marcB[] = new byte[5];
                        System.arraycopy(bytes, 0, marcB, 0, 5);

                        String marcS = new String(marcB);
                        int marcLen = Integer.parseInt(marcS);
                        // 读取数据基地址
                        byte marcB2[] = new byte[5];
                        System.arraycopy(bytes, 12, marcB2, 0, 5);
                        String marcS2 = new String(marcB2);
                        int dataStart = Integer.parseInt(marcS2);
                        // 读取次目录区数据
                        int cmLength = dataStart - 24 - 1;
                        byte marcB3[] = new byte[cmLength];
                        System.arraycopy(bytes, 24, marcB3, 0, cmLength);

                        byte[] LDR = new byte[24];
                        System.arraycopy(bytes, 0, LDR, 0, 24);

                        cnmarc = new CNMARC("LDR", CNMARC.getKeyName("LDR"), "", new String(LDR));
                        cnmarcs.put("LDR", cnmarc);

                        // 读取记录控制信息
                        String marcS3 = new String(marcB3);
                        int n = cmLength / 12;
                        String controls[] = new String[n];
                        for(int i = 0; i < n; i++){
                            controls[i] = marcS3.substring(i * 12, (i + 1) * 12);
                        }
                        // 读取数据区信息
                        int dataLength = bytes.length - dataStart - 1;//marcLen - dataStart - 1;
                        byte data[] = new byte[dataLength];

                        System.arraycopy(bytes, dataStart, data, 0, dataLength);

                        for(int i = 0; i < n; i++){
                            String key = controls[i].substring(0, 3);
                            int length = Integer.parseInt(controls[i].substring(3, 7));
                            int start = Integer.parseInt(controls[i].substring(7));
                            byte temp[] = new byte[length];
                            try{
                                System.arraycopy(data, start, temp, 0, length);
                                String content = new String(temp, charsetName);

                                cnmarc = new CNMARC(key, CNMARC.getKeyName(key), "", content);
                                cnmarcs.put(key, cnmarc);

                            }
                            catch(Exception e){
                                logger.error(e.getMessage());
                            }
                            //System.out.print(OKData[i][0] + "  ");
                            //System.out.println(controls[i].substring(7) + " " + controls[i].substring(3, 7) + " ");
                            //System.out.println(content);
                            //System.out.println();
                        }
                        BkBookinfo bookinfo = new BkBookinfo(bookInfoStr, cnmarcs);
                        bookInfoList.add(bookinfo);
                    }
                    catch(Exception e){
                        temBookInfoStr = bookInfoStr;
                        logger.error(e.getMessage());
                    }
                }
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }
        return bookInfoList;
    }

    public static String getNum(int count, int barCodeLength){
        // 格式化数字 生成 0000000001格式
        String pattern = "";
        for(int i = 0; i < barCodeLength; i++){
            pattern += "0";
        }

        DecimalFormat df = new DecimalFormat(pattern);
        return df.format(count);
    }

    public static int getWordlength(String s){
        s = s.replaceAll("[^\\x00-\\xff]", "**");
        return s.length();
    }
}
